feat: Featured Snippets, search and filtering for Community page#383
feat: Featured Snippets, search and filtering for Community page#383code-snippets-bot wants to merge 29 commits into
Conversation
Add get_featured_snippets() to Cloud_API that fetches from the cloud /api/v1/featured endpoint with transient caching derived from the cached_until response field. Add /cloud/featured REST route to expose featured snippets to the frontend.
Load featured snippets on the Community Cloud page when no search query is active. The frontend context fetches from the /cloud/featured REST endpoint on mount and displays results under a "Featured Snippets" heading. When the user performs a search, normal search behaviour takes over. Add PHPUnit tests covering transient caching, cache-hit bypass, and graceful fallback on HTTP errors.
Add 3 additional PHPUnit tests: TTL respects cached_until, missing data key returns empty result, and transient stores Cloud_Snippets instance. Add Playwright E2E spec for community cloud page covering page load, featured heading display, and search override behavior.
There was a problem hiding this comment.
This PR is clean!
The only suggestion I can make is to mock the responses via Playwright page.route() + route.fulfill() with fixed JSON and X-WP-Total / X-WP-TotalPages headers. That avoids depending on a live cloud/API, removes flakiness from timeouts and env differences, and lets us assert the featured heading, row content, and “search hides featured” etc deterministically. Happy for this to land as a follow-up.
|
PlayWright tests are failing |
| const requestId = nextRequestId() | ||
| setIsSearching(true) | ||
|
|
||
| api.getResponse<CloudSnippetSchema[]>( |
There was a problem hiding this comment.
Huge amount of duplicated code here.
| return | ||
| } | ||
|
|
||
| clearTimeout(searchTimerRef.current) |
There was a problem hiding this comment.
What's the purpose of the timeout? Are we worried about requests to the API taking too long in a way that Axios is unprepared to handle?
| const [error, setError] = useState(false) | ||
| const [isFeatured, setIsFeatured] = useState(false) | ||
|
|
||
| const searchTimerRef = useRef<ReturnType<typeof setTimeout>>() |
There was a problem hiding this comment.
I do not understand the use of useRef here instead of useState.
| 'site_host' => wp_parse_url( get_site_url(), PHP_URL_HOST ), | ||
| ]; | ||
|
|
||
| foreach ( [ 'category', 'type', 'status' ] as $key ) { |
There was a problem hiding this comment.
Is there actually any difference between passing these parameters with empty values versus not passing them at all?
| delete_transient( self::CATEGORIES_TRANSIENT_KEY ); | ||
| delete_transient( 'cs_codevault_snippets' ); | ||
|
|
||
| $wpdb->query( |
There was a problem hiding this comment.
I think it'd be much better to avoid a direct DB query here if we can avoid it, especially on a core table. Is there a reason why delete_transient can't do the job for us?
Summary
Community Snippets page now shows featured snippets on initial load and supports server-side filtering with category, type, and status dropdowns. Filter options come from the full query result via independent facets.
Featured Snippets
Server-Side Filters
New Endpoints Proxied
Cloud Snippet Model
UI
Test plan